#ifndef __GLF_CORE_BITS_H_INCLUDED__
#define __GLF_CORE_BITS_H_INCLUDED__

#include <glf/config.h>

namespace glf {

#ifdef WIN32

#include <intrin.h>

// Find First Set (MSVC implementation).
// Returns the position of the first (least significat) bit set to 1.
inline unsigned long Ffs(unsigned long value)
{
	GLF_ASSERT(value);

	unsigned long r;
	_BitScanForward(&r, value);
	return r;
}

// Find Last Set (MSVC implementation).
// Returns the position of the last (most significat) bit set to 1.
inline unsigned long Fls(unsigned long value)
{
	GLF_ASSERT(value);

	unsigned long r;
	_BitScanReverse(&r, value);
	return r;
}

#else // WIN32

// Find First Set (C implementation).
// Returns the position of the first (least significat) bit set to 1.
inline unsigned long Ffs (unsigned long value)
{
	GLF_ASSERT(value);

	unsigned long bit;
	for (bit = 0; !(value & 1); ++bit)
	{
		value >>= 1;
	}

  return bit;
}

// Find Last Set (C implementation).
// Returns the position of the last (most significat) bit set to 1.
inline unsigned long Fls (unsigned long value)
{
	GLF_ASSERT(value);

	const unsigned long last_bit = sizeof(unsigned long) * CHAR_BIT - 1;

	unsigned long bit;
	for (bit = last_bit; !(value & (1 << last_bit)); --bit)
	{
		value <<= 1;
	}

  return bit;
}

#endif // WIN32

} // end namespace glf

#endif // __GLF_CORE_BITS_H_INCLUDED__
